﻿#ifndef  XC_BASE_H
#define  XC_BASE_H

//@隐藏{
#define WIN32_LEAN_AND_MEAN    // 从 Windows 头文件中排除极少使用的内容

#include <stdio.h>
#include <memory>
#include <string>
#include <vector>
#include <map>
#include <windows.h>
#include <time.h>
#include <shellapi.h>
using namespace std;
//@隐藏}

//@模块名称  基础模块  
//@版本  1.0  
//@日期  2020-10-23
//@作者  XCGUI  
//@模块备注 基础功能模块

//@src "module_base.cpp"

// #if XC_MOUDLE
// #endif


//@隐藏{
#ifdef _WIN64
typedef  __int64  vint;
#else
typedef  int      vint;
#endif

#define  cx_iterator  auto

//@隐藏}

/*@声明
DECLARE_HANDLEX(HINSTANCE);
DECLARE_HANDLEX(HCURSOR);
DECLARE_HANDLEX(HFONT);
DECLARE_HANDLEX(HDC);
DECLARE_HANDLEX(HBRUSH);
DECLARE_HANDLEX(HPEN);
DECLARE_HANDLEX(HRGN);
DECLARE_HANDLEX(HWND);
DECLARE_HANDLEX(HMODULE);
DECLARE_HANDLEX(FARPROC);
DECLARE_HANDLEX(HANDLE);
*/

//@分组{ 核心组

#define  out_
#define  in_
#define  out_in_

/*@声明
class string
{
public:
	//@别名  取地址()
	const char* c_str();
};

class wstring
{
public:
	//@别名  取地址()
	const wchar_t* c_str();
};
*/

//----------CXBytes------------------------------------------
class CXText;

//@备注 字节集末尾隐藏2个字节(00终止符),以防止字符串越界, size()获取长度不包含终止符
//@别名 字节集
class CXBytes
{
public:
	//@隐藏{
	CXBytes();
	CXBytes(const CXBytes& _that);
	CXBytes(CXBytes&& _that);
	CXBytes(const wchar_t* pText);
	CXBytes(const char* pText);
	~CXBytes();
	void Init();

	operator const char*() const { return _data; } //当作为函数参数传递时, 自动转换为[const char*]
	BOOL operator==(const CXBytes& _that);
	
	void operator=(const CXBytes& _that);
	void operator=(CXBytes&& _that);
	void operator=(const wchar_t* pText);
	void operator=(const char* pText);
	//@隐藏}
	CXBytes operator+(const CXBytes& _that);
	void operator+=(const CXBytes& _that);
	BYTE operator[](int pos);

	//@备注 如果旧数据是引用的数据, 那么将断开旧数据的引用,作为新的实例
	//@别名 置大小(大小)
	char* alloc(UINT length);

	//@备注 如果旧数据是引用的数据, 那么将断开旧数据的引用,作为新的实例
	//@别名 追加大小(大小)
	void addSize(UINT length);

	//@备注 如果旧数据是引用的数据, 那么将断开旧数据的引用,作为新的实例
	//@别名 追加数据(数据地址, 数据长度)
	void add(void* data, int length);

	//@别名 追加文本()
	void addText(const wchar_t*  pText);

	//@别名 追加文本A()
	void addTextA(const char* pText);

	//@别名  追加整型()
	void addInt(int value_);

	//@别名  追加无符号整型()
	void addUInt(unsigned int value_);

	//@别名  追加短整型()
	void addShort(short value_);

	//@别名  追加无符号短整型()
	void addUShort(unsigned short value_);

	//@别名  追加短浮点型()
	void addFloat(float value_);

	//@别名  追加浮点型()
	void addDouble(double value_);

	//@别名  追加字符型()
	void addWchar(wchar_t value_);

	//@别名  追加字节型()
	void addByte(BYTE value_);

	//@别名 追加十六进制()
	BOOL addHex(const wchar_t* pHex);

	//@别名 取十六进制文本()
	CXText  getHexToText();

	//@别名 取文本指针()
	const wchar_t* getTextPtr();

	//@别名 取文本指针A()
	const char* getTextPtrA();

	//@别名  取整型(位置)
	int getInt(int pos=0);
	
	//@别名  取无符号整型(位置)
	unsigned int getUInt(int pos = 0);

	//@别名  取短整型(位置)
	short getShort(int pos = 0);

	//@别名  取无符号短整型(位置)
	unsigned short getUShort(int pos = 0);

	//@别名  取短浮点型(位置)
	float getFloat(int pos = 0);

	//@别名  取浮点型(位置)
	double getDouble(int pos = 0);

	//@别名  取字符型(位置)
	wchar_t getWchar(int pos = 0);

	//@别名  取字节型(位置)
	BYTE getByte(int pos = 0);

	//@别名 置空()
	void  clear();

	//@别名 大小()
	int  size() { return _length; }

	//@别名 取地址()
	char* get() { return _data; }

	//@备注 如果旧数据是引用的数据, 那么将断开旧数据的引用,作为新的实例
	//@别名 置数据(数据地址, 数据长度)
	void set(void* data, int length);

	//@别名 置文本()
	void setText(const wchar_t *pText);

	//@别名 置文本A()
	void setTextA(const char* pText);

	//@别名 置十六进制文本()
	void setHexText(const wchar_t* pHex);

	//@别名 取左边(长度)
	CXBytes getLeft(int length);

	//@别名 取右边(长度)
	CXBytes getRight(int length);

	//@别名 取中间(开始位置索引, 长度)
	CXBytes getMid(int iStart, int length);

private:
	void  move() { _bOwner = FALSE; } //析构时保存内存数据
	char*   _data;
	int     _length;   //总长度 不包含隐藏的终止字符 
	BOOL    _bOwner;

	BYTE hexCharToByte(wchar_t c);
};

//@备注 文本操作类
//@别名 文本
class CXText
{
public:
	//@隐藏{
	CXText();
	CXText(const CXText& _that);
	CXText(CXText&& _that);//移动构造函数
	CXText(const wstring& wstring_) {_bOwner = TRUE; _text = new std::wstring;  *_text = wstring_; }
	CXText(const wchar_t* pText) {_bOwner = TRUE; _text = new std::wstring; if (pText) *_text = pText; }
	CXText(CXBytes &_that);
	~CXText() {if (_bOwner)	delete _text;}
	
	void operator=(const wchar_t* pText) {*_text = pText ? pText : L""; }
	void operator=(const wstring& wstring_) {*_text = wstring_; }
	void operator=(const CXText &_that) {*_text = *(_that._text);}
	void operator=(CXBytes &_that);
	void operator=(CXText&& _that) {
		if (_bOwner) delete _text;
		_bOwner = TRUE;
		_text = _that._text;
		_that.move();
	}
	bool operator>(const CXText& right) const { return (_text->compare(*right._text) > 0); }
	
	bool operator<(const CXText& right) const { return (_text->compare(*right._text) < 0); }
	bool operator!=(const CXText& right) const { return (_text->compare(*right._text) != 0); }
	bool operator!=(const wchar_t* right) const { return (_text->compare(right) != 0); }

	bool operator==(const CXText& right) const { return *_text == *right._text; }
	bool operator==(const wchar_t* right) const { return *_text == right; }
	friend bool operator==(const wchar_t* left, const CXText& right) { return right.equal(left); }
	friend CXText operator+(const wchar_t* left, const CXText& right) { CXText  text = left; text += right;	return text; }

	operator const wchar_t*() const { return (_text->c_str()); }//当作为函数参数传递时, 自动转换为[const char*]
	bool equal(const CXText &right) const { return  *_text == *right._text; }
//@隐藏}
	CXText operator+(const wchar_t ch) const {
		CXText  ret = *this;
		ret += ch;
		return ret;
	}
	CXText operator+(const wchar_t* pText) const { 
		CXText  ret = *this; 
		ret += pText; 
		return ret; }

	void operator+=(const wchar_t ch) const { (*_text) += ch; }
	void operator+=(const wchar_t* pText) const { (*_text) += pText; }
	wchar_t operator[](int pos) { return (*_text)[pos]; }

	//@别名  取地址()
	const wchar_t* get() const { return _text->c_str(); }

	//@别名 大小()
	int  size()const { return _text->size(); }
	//@别名 置大小(长度)
	void resize(UINT length)const { _text->resize(length); };

	//@别名 是否为空()
	BOOL empty(){if(_text)	return _text->empty();return TRUE;}

private:
	void move() { _bOwner = FALSE;}
	std::wstring*  _text;
	BOOL   _bOwner;
};


//@备注 文本操作类A
//@别名 文本A
class CXTextA
{
public:
	//@隐藏{
	CXTextA();
	CXTextA(const CXTextA& _that);
	CXTextA(CXTextA&& _that);
	CXTextA(const string &string_) { _bOwner = TRUE; _text = new std::string; *_text = string_; }
	CXTextA(const char* pText) { _bOwner = TRUE; _text = new std::string; if (pText) *_text = pText; }
	CXTextA(CXBytes &_that);
	~CXTextA() { if (_bOwner) delete _text; }

	void operator=(const char* pText) { *_text = pText ? pText : ""; }
	void operator=(const string& string_) { *_text = string_; }
	void operator=(const CXTextA &_that) { *_text = *(_that._text); }
	void operator=(CXBytes &_that);

	void operator=(CXTextA&& _that) {
		if (_bOwner) delete _text;
		_bOwner = TRUE;
		_text = _that._text;
		_that.move();
	}
	bool operator>(const CXTextA& right) const { return (_text->compare(*right._text) > 0); }
	
	bool operator<(const CXTextA& right) const { return (_text->compare(*right._text) < 0); }
	bool operator!=(const CXTextA& right) const { return (_text->compare(*right._text) != 0); }
	bool operator!=(const char* right) const { return  (_text->compare(right) != 0); }

	bool operator==(const CXTextA& right) { return *_text == *right._text; }
	bool operator==(const char* right) { return  *_text == right; }
	friend bool operator==(const char* left, const CXTextA& right) { return right.equal(left); }
	friend CXTextA operator+(const char* left, const CXTextA& right) { CXTextA  text = left; text += right;	return text; }

	operator const char*() const { return(_text->c_str()); } //当作为函数参数传递时, 自动转换为[const char*]
	bool equal(const CXTextA &_right) const { return (*_text == *_right._text); }
//@隐藏}

	CXTextA operator+(const char ch) const {
		CXTextA  ret = *this;
		ret += ch;
		return ret;
	}
	CXTextA operator+(const char* pText) const {
		CXTextA  ret = *this;
		ret += pText;
		return ret;
	}

   	void operator+=(const char ch) const { (*_text) += ch; }
	void operator+=(const char* pText) const { (*_text) += pText; }
//	void operator+=(const CXTextA& _that) { (*_text) += (*_that._text); }
	wchar_t operator[](int pos) { return (*_text)[pos]; }

	//@别名  取地址()
	const char*  get() const { return _text->c_str(); }
	//@别名 大小()
	int  size()const { return _text->size(); }
	//@别名 置大小(长度)
	void resize(UINT length)const { _text->resize(length); };
	//@别名 是否为空()
	BOOL empty() { if (_text)	return _text->empty(); return TRUE; }
private:
	void move() { _bOwner = FALSE; }
	std::string*  _text;
	BOOL   _bOwner;
};

//@别名 动态数组
//@隐藏{
template<class T>
//@隐藏}
class CXVector
{
public:
//@隐藏{
	CXVector() { _bOwner = TRUE, _list = new vector<T>; }
	~CXVector() { if (_bOwner) delete _list; }
	CXVector(CXVector&& _that) {_that.move();_bOwner = TRUE;_list = _that._list;}
	CXVector(CXVector& _that) { _bOwner = TRUE;  _list = new vector<T>; *_list = *_that._list; }
	T& operator[](int pos) { return (*_list)[pos]; }
	void operator=(const CXVector& _that) { *_list = *(_that._list); }
	CXVector operator+(const CXVector& _that) {
		CXVector<T> ret = *this;
		ret += _that;
		return ret;
	}
	void operator+=(const CXVector& _that) {
		for (auto var : *_that._list)
			_list->push_back(var);
	}
//@隐藏}
	//@别名 取首()
	T front() { return  _list->front(); }	
	//@别名 取尾()
	T back() { return  _list->back(); }
	//@别名 置大小(大小)
	void resize(int size) { _list->resize(size); }		
	//@别名 大小()
	int size() { return  _list->size(); }
	//@别名 添加(值)
	void add(T value) { _list->push_back(value); }
	//@别名 是否为空()
	bool empty() { return _list->empty(); }
	//@别名 删除()
	void erase(int pos) { _list->erase(_list->begin() + pos); }
	//@别名 删除扩展()
	void erase(int first_, int last_) { _list->erase(_list->begin() + first_, _list->begin() + last_); }
	//@别名  清空()
	void clear() { _list->clear(); }
//@隐藏{
	std::vector<T>*  getVector() { return _list; }
//@隐藏}
private:
	void move() { _bOwner = FALSE; }
	std::vector<T>  *_list;
	BOOL   _bOwner;
};

//-------------map-------------------------------------

/*@声明
//@别名 迭代器
class cx_iterator
{
	//@别名  键
	void first;

	//@别名  值
	void second;
};
*/

//@别名 字典
//@隐藏{
template<class K, class V>
//@隐藏}
class CXMap
{
public:
//@隐藏{
	typedef typename  std::map<K,V>::iterator  iterator;
	CXMap() {_bOwner = TRUE; _map = new std::map<K, V>;	}
	~CXMap() { if (_bOwner) delete _map; }
	CXMap(CXMap&& _that) { _that.move(); _bOwner = TRUE; _map = _that._map; }
	CXMap(CXMap& _that) { _bOwner = TRUE;  _map = new std::map<K,V>; *_map = *_that._map; }

	V& operator[](K key_){	return (*_map)[key_];}
	void operator=(const CXMap& _that) { *_map = *(_that._map); }
	CXMap operator+(const CXMap& _that) {
		CXMap<K,V> ret = *this;
		ret += _that;
		return ret;
	}
	void operator+=(const CXMap& _that) {
		for (auto var : *_that._map)
			(*_map)[var.first] = var.second;
	}
//@隐藏}
	//@别名 大小()
	int size() { return _map->size(); }
	//@别名 查找()
	cx_iterator find(K  key_) { return _map->find(key_); }
	//@别名 第一个()
	cx_iterator begin() { return _map->begin(); }
	//@别名 空值()
	cx_iterator end() { return _map->end(); }
	//@别名 是否为空()
	cx_iterator empty() { return _map->empty(); }
	//@别名 删除()
	cx_iterator erase(K key_) { return _map->erase(key_); }
	//@别名  清空()
	void clear() { _map->clear(); }
//@隐藏{
	std::map<K, V>* getMap() { return _map; }
//@隐藏}
private:
	void move() { _bOwner = FALSE; }
	std::map<K, V>* _map;
	BOOL   _bOwner;
};

//@分组}   核心组

//-----------------------------------------------
//@分组{   编码转换

//@参数 pString utf8字节集指针
//@备注 UTF8到W
CXText U2W(const char *utf8, int length = -1);

//@参数 pString Unicode文本指针
//@备注 W到UTF8
CXBytes W2U(const wchar_t *pString, int length = -1);

//@参数 pString Unicode文本指针
//@参数 length 长度
//@备注 将Unicode转成Ansi
//@别名 W2A_(Unicode文本指针,长度)
CXTextA W2A_(const wchar_t* pString, int length = -1);
//@参数 pString Ansi文本
//@参数 length 长度
//@备注 将Ansi转成Unicode
//@别名 A2W_(Ansi文本,长度)
CXText  A2W_(const char* pString, int length = -1);

//@备注  使用共享内存块
const char* W2A_temp(const wchar_t* pString);

//@备注  使用共享内存块
const wchar_t*  A2W_temp(const char* pString);
//@分组}

//--------------------------------------------
//@分组{   数值转换

//@别名 整型到文本A()
const char* XC_itoa_temp(int nValue);

//@别名 整型到文本()
const wchar_t* XC_itow_temp(int nValue);

//@别名 整型64到文本()
const wchar_t* XC_i64tow_temp(__int64 nValue);

//@别名 浮点型到文本A()
const char*    XC_ftoa_temp(float fValue);

//@别名 浮点型到文本()
const wchar_t* XC_ftow_temp(float fValue);

//@别名 双精度浮点型到文本()
const wchar_t* XC_fftow_temp(double fValue);

//@别名 整型到十六进制()
const wchar_t* XC_itohex_temp(int value_);

//@别名 文本到浮点型()
static float xc_wtof(const wchar_t* pText) { 
	wchar_t* stopstring;
	return wcstof(pText, &stopstring);
}

/*@声明
//@别名 文本到整型()
int _wtoi(const wchar_t* pText);

//@别名 文本到整型64()
__int64 _wtoi64(const wchar_t* pText);

//@别名 文本到双精度浮点型()
double _wtof(const wchar_t* pText);

//@别名 取绝对值()
#define abs(...);

//@别名 取最大值()
#define min(...)

//@别名 取最小值()
#define max(...)
*/

//@分组}


//--------------------------------------------
//@分组{ 内存操作
/*@声明
//@参数 dest 指向用于存储复制内容的目标数组，类型强制转换为 void* 指针。
//@参数 src 指向要复制的数据源，类型强制转换为 void* 指针
//@参数 count 要被复制的字节数
//@别名 内存复制A(存储数据,要复制的数据,复制的字节数)
//@备注 从源source所指的内存地址的起始位置开始拷贝n个字节到目标destin所指的内存地址的起始位置中
//@返回 该函数返回一个指向目标存储区destin的指针。
void *memcpy(void *dest,const void *src,size_t count);

//@参数 dest 指向用于存储复制内容的目标数组，类型强制转换为 void* 指针。
//@参数 src 指向要复制的数据源，类型强制转换为 void* 指针
//@参数 count 要被复制的字节数
//@别名 内存复制(存储数据,要复制的数据,复制的字节数)
//@备注 从源source所指的内存地址的起始位置开始拷贝n个字节到目标destin所指的内存地址的起始位置中
//@返回 该函数返回一个指向目标存储区destin的指针。
wchar_t *wmemcpy(wchar_t *dest,const wchar_t *src,size_t count);

//@参数 buf1 指向内存块的指针
//@参数 buf2 指向内存块的指针
//@参数 count 要被比较的字节数
//@别名 内存比较A(内存块指针1,内存块指针2,字节数)
//@备注 比较内存区域buf1和buf2的前count个字节。
//@返回 如果返回值 < 0，则表示 str1 小于 str2。如果返回值 > 0，则表示 str2 小于 str1。如果返回值 = 0，则表示 str1 等于 str2。
int memcmp(const void *buf1,const void *buf2,size_t count);

//@参数 buf1 指向内存块的指针
//@参数 buf2 指向内存块的指针
//@参数 count 要被比较的字节数
//@别名 内存比较(内存块指针1,内存块指针2,字节数)
//@备注 比较内存区域buf1和buf2的前count个字节。
int wmemcmp(const wchar_t * buf1,const wchar_t * buf2,size_t count);

//@别名 内存比较扩展A()
errno_t memcpy_s(void *dest,  size_t numberOfElements,  const void *src,  size_t count );

//@别名 内存比较扩展()
errno_t wmemcpy_s(  wchar_t *dest,  size_t numberOfElements,  const wchar_t *src,  size_t count);

//@参数 size 内存块大小，以字节为单位。
//@别名 内存分配(大小)
//@备注 分配所需的内存空间，并返回一个指向它的指针。
void *malloc(size_t size);

//@参数 memblock 内存块指针
//@别名 内存释放(内存块指针)
//@备注 该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果传递的参数是一个空指针，则不会执行任何动作。
void free(void *memblock);

*/

//@分组}

//----------------------------------------------


//@分组{  文本操作

/*@声明

//@参数 欲组合的文本 类型为“字符型（wchar_t）”
//@返回 组合后的文本
//@备注 不限参数
//@别名 文本组合()
CXText  mkStr(...);

//@参数 目标文本 类型为“字符型A（char）”
//@参数 字节大小 类型为“无符号整型（size_t）(注:内容大小不能超过这个数)”
//@参数 源文本 类型为“字符型A（char）”
//@别名 文本复制A(目标文本,字节,源文本)
errno_t strcpy_s(char *strDestination,size_t numberOfElements,const char *strSource);

//@参数 目标文本 类型为“字符型（wchar_t）”
//@参数 字节大小 类型为“无符号整型（size_t）(注:内容大小不能超过这个数)”
//@参数 源文本 类型为“字符型（wchar_t）”
//@别名 文本复制(目标文本,字节,源文本)
errno_t wcscpy_s(wchar_t *strDestination,size_t numberOfElements,const wchar_t *strSource);

//@参数 欲被搜索的宽字符串 类型为“字符型A（char）”
//@参数 要搜索的宽字符串 类型为“字符型A（char）”
//@返回 若成功则返回一个指向后者第一次出现的位置，否则返回NULL 本命令为初级命令。
//@别名 文本查找A(欲被搜索的宽字符串,要搜索的宽字符串)
char *strstr(const char *str,const char *strSearch);

//@参数 欲被搜索的宽字符串 类型为“字符型（wchar_t）”
//@参数 要搜索的宽字符串 类型为“字符型（wchar_t）”
//@返回 若成功则返回一个指向后者第一次出现的位置，否则返回NULL 本命令为初级命令。
//@别名 文本查找(欲被搜索的宽字符串,要搜索的宽字符串)
wchar_t *wcsstr(const wchar_t *str,const wchar_t *strSearch);

//@参数 被添加的文本 类型为“字符型A（char）”
//@参数 字节大小 类型为“无符号整型（size_t）(注:内容大小不能超过这个数)”
//@参数 添加的文本 类型为“字符型A（char）”
//@别名 文本拼接A(被添加的字符串,字节,添加的字符串)
errno_t strcat_s(char *strDestination,size_t numberOfElements,const char *strSource);

//@参数 被添加的字符串 类型为“字符型（wchar_t）”
//@参数 字节大小 类型为“无符号整型（size_t）(注:内容大小不能超过这个数)”
//@参数 添加的字符串 类型为“字符型（wchar_t）”
//@别名 文本拼接(被添加的字符串,字节,添加的字符串)
errno_t wcscat_s(wchar_t *strDestination,size_t numberOfElements,const wchar_t *strSource);

//@参数 文本数据 类型为“字符型A（char）”。参数值指定欲检查其长度的文本数据。
//@返回 取字符串数据的长度，不包括\0在内。本命令为初级命令。
//@别名 文本取长度A(文本数据)
UINT strlen(const char *str);

//@参数 文本数据 类型为“字符型（wchar_t）”。参数值指定欲检查其长度的文本数据。
//@返回 取字符串数据的长度。本命令为初级命令。
//@别名 文本取长度(文本数据)
UINT wcslen(const wchar_t *str);

//@参数 待比较文本一 类型为“字符型A（char）”
//@参数 待比较文本二 类型为“字符型A（char）”
//@返回 如果返回值小于0，表示文本一小于文本二；如果等于0，表示文本一等于文本二；如果大于0，表示文本一大于文本二。本命令为初级命令。
//@别名 文本比较A(待比较文本一,待比较文本二)
int strcmp(const char *string1, const char *string2);

//@参数 待比较文本一 类型为“字符型（wchar_t）”
//@参数 待比较文本二 类型为“字符型（wchar_t）”
//@返回 如果返回值小于0，表示文本一小于文本二；如果等于0，表示文本一等于文本二；如果大于0，表示文本一大于文本二。本命令为初级命令。
//@别名 文本比较(待比较文本一,待比较文本二)
int wcscmp( const wchar_t *string1, const wchar_t *string2);

//@参数 待比较文本一 类型为“字节型（BYTE）”
//@参数 待比较文本二 类型为“字节型（BYTE）”
//@返回 如果返回值小于0，表示文本一小于文本二；如果等于0，表示文本一等于文本二；如果大于0，表示文本一大于文本二。本命令为初级命令。
//@别名 文本比较_(待比较文本一,待比较文本二)
int _mbscmp( const unsigned char *string1, const unsigned char *string2);

*/
//@分组}  文本操作

//@分组{ 文件操作
//@别名 文件类
class CXFile
{
//@备注  文件指针
	FILE*  m_pFile;
public:
	CXFile();
	~CXFile();
//@备注  打开以进行读取和追加。追加操作包括在新数据写入文件之前移除 EOF 标记。 
//写入完成后，EOF 标记不会还原。
//如果文件不存在，则创建文件。
//@别名  打开(文件名)
	BOOL open(const wchar_t* pFileName);      //读写追加模式

//@备注  打开以便读取。如果文件不存在或找不到，调用将失败
//@别名  打开只读(文件名)
	BOOL openRead(const wchar_t* pFileName);  //只读模式

//@备注 打开用于读取和写入的空文件。 如果文件存在，则其内容会被销毁
//@别名 打开写入(文件名)
	BOOL openWrite(const wchar_t* pFileName);   //打开空文件写入

//@备注 模式说明参加MSDN
//@别名 打开指定模式(文件名, 模式字符串)
	BOOL openEx(const wchar_t* pFileName, const wchar_t* pMode); //扩展

//@别名 关闭()
	void close();

//@别名 取长度()
	UINT getLength(); //获取文件长度

//@别名 移动到首()
	BOOL seekBegin(); //移动到文件首
//@别名 移动到尾()
	BOOL seekEnd(); //移动到文件尾

//@参数 offset  偏移量
//@参数 origin  SEEK_CUR:文件指针的当前位置,  SEEK_END:文件结尾, SEEK_SET:文件开头,
//@别名 移动读写位置(偏移量, 起始位置)
	BOOL seekPos(int offset, int origin); //移动读写位置

//@参数 buf 内存块指针
//@参数 bufSize 内存块大小
//@返回 返回读取长度
//@别名 读取数据(内存块指针, 读取长度)
	UINT readData(out_ void* buf, in_ int nBufSize);

//@参数 buf 内存块指针
//@参数 nBufSize 内存块大小
//@备注 按行读取
//@别名 读取数据行(内存块指针, 读取长度)
	BOOL readDataRow(out_ char* buf, in_ int nBufSize);  //取一行文本

//@参数 nLength 读取长度, -1读取全部
//@别名 读取到字节集(读取长度)
	CXBytes readDataBytes(int nLength=-1); //读取数据到字节集

//@参数 data 数据指针
//@参数 nLength 数据长度
//@返回 返回写入长度
//@别名 写入数据(数据指针, 写入长度)
	UINT writeData(const void* data, int nLength); //写入数据

//@参数 data 数据指针
//@参数 nLength 数据长度
//@返回 返回写入长度, 字符为单位
//@别名 写入文本指针(数据指针, 写入长度)
	UINT writeTextPtr(const wchar_t* data, int nLength = -1);

//@参数 data 数据指针
//@参数 nLength 写入长度, -1写入全部, 字符为单位
//@返回 返回写入长度
//@别名 写入文本指针A(数据指针, 写入长度)
	UINT writeTextPtrA(const char* data, int nLength = -1);

//@参数 text 文本
//@参数 nLength 写入长度, -1写入全部, 字符为单位
//@返回 返回写入长度
//@别名 写入文本(文本,写入长度)
	UINT writeText(CXText text, int nLength = -1);

//@参数 text 文本
//@参数 nLength 写入长度, -1写入全部, 字符为单位
//@返回 返回写入长度
//@别名 写入文本A(文本,写入长度)
	UINT writeTextA(CXTextA text, int nLength = -1);

//@别名 是否在文件尾()
	BOOL isEof();
};
//@备注 创建文件夹及子文件夹,如果文件夹不存在则创建
//@参数 pPath 路径, 文件夹路径
//@别名 创建文件夹扩展(路径)
BOOL xc_createFolders(const wchar_t*  pPath);

//@备注 复制文件自动创建路径
//@参数 dest 目标文件, 保存到目标文件路径
//@参数 dest 源文件, 要复制的文件
//@别名 复制文件扩展(目标文件, 源文件)
BOOL xc_copyFile(const wchar_t* dest, const wchar_t*  src);

//@分组}

//@分组{  文件查找

/*@声明
//@别名 结构_文件时间属性
struct FILETIME {
//@别名 低32位的时间值
	DWORD  dwLowDateTime;
//@别名 高32位的时间值
	DWORD  dwHighDateTime;
};
//@别名 结构_文件信息
struct WIN32_FIND_DATAW {
//@别名 文件属性
	DWORD   dwFileAttributes;
//@别名 创建日期
	FILETIME   ftCreationTime;
//@别名 最后存取日期
	FILETIME   ftLastAccessTime;
//@别名 最后修改日期
	FILETIME   ftLastWriteTime;
//@别名 长度高32位
	DWORD    nFileSizeHigh;
//@别名 长度低32位
	DWORD    nFileSizeLow;
//@别名 内部使用
	DWORD    dwReserved0;
//@别名 内部使用
	DWORD    dwReserved1;
//@别名 文件名
	WCHAR    cFileName[MAX_PATH];
//@别名 短文件名
	WCHAR    cAlternateFileName[14];
};

//@参数 欲搜索的文件名 类型为“字符型（wchar_t）”，参数可如下：c:\Windows\*.*，详见MSDN
//@参数 文件信息 类型为“数据类型（WIN32_FIND_DATAW）”，这个结构用于装载与找到的文件有关的信息。该结构可用于后续的搜索
//@返回 Long，如执行成功，返回一个搜索句柄。如果出错，返回一个INVALID_HANDLE_VALUE常数，一旦不再需要，应该用FindClose函数关闭这个句柄
//@备注 由这个函数返回的句柄可以作为一个参数用于FindNextFile函数。这样一来，就可以方便的枚举出与lpFileName参数指定的文件名相符的所有文件
//@别名 查找第一个文件(欲搜索的文件名,文件信息)
HANDLE WINAPI FindFirstFile(const wchar_t* lpFileName, out_ WIN32_FIND_DATAW* lpFindFileData);

//@参数 文件句柄 类型为“HANDLE（HANDLE）”，上一次查找返回的文件句柄
//@参数 文件信息 类型为“数据类型（WIN32_FIND_DATAW）”，这个结构用于装载与找到的文件有关的信息。该结构可用于后续的搜索
//@返回 Long，如执行成功，返回TRUE。否则为FALSE。
//@备注 此函数用于遍历目录或文件时，判断当前目录下是否有下一个目录或文件 
//@别名 查找下一个文件(文件句柄, 文件信息)
BOOL WINAPI FindNextFile(HANDLE hFindFile, out_ WIN32_FIND_DATAW* lpFindFileData);
*/

//@分组}


//----------------------

//@分组{  日期时间

/*@声明

//@备注 检索自系统启动以来经过的毫秒数，最长为49.7天。
//@别名 取系统时钟()
DWORD GetTickCount();

struct tm
{
	//@备注 秒 – 取值区间为[0,59]
	//@别名 秒数
	int tm_sec;   // seconds after the minute - [0, 60] including leap second
	
	//@备注 分 - 取值区间为[0,59] 
	//@别名 分钟
	int tm_min;   // minutes after the hour - [0, 59]

	//@备注 时 - 取值区间为[0,23]
	//@别名 小时
	int tm_hour;  // hours since midnight - [0, 23]

	//@备注 一个月中的日期 - 取值区间为[1,31] 
	//@别名 日
	int tm_mday;  // day of the month - [1, 31]

	//@备注 月份（从一月开始，0代表一月） - 取值区间为[0,11]
	//@别名 月
	int tm_mon;   // months since January - [0, 11]

	//@备注 年份，其值等于实际年份减去1900
	//@别名 年
	int tm_year;  // years since 1900

	//@备注 星期 – 取值区间为[0,6]，其中0代表星期天，1代表星期一，以此类推
	//@别名 星期
	int tm_wday;  // days since Sunday - [0, 6]

	//@备注 从每年的1月1日开始的天数 – 取值区间为[0,365]，其中0代表1月1日，1代表1月2日，以此类推
	//@别名 年日
	int tm_yday;  // days since January 1 - [0, 365]

	//@备注 对于 gmtime ，始终为0。夏令时标识符，实行夏令时的时候，tm_isdst为正。不实行夏令时的时候，tm_isdst为0；不了解情况时，tm_isdst()为负
	//@别名 夏令时
	int tm_isdst; // daylight savings time flag
};
*/

//@别名 日期时间
class  CSysDateTime
{
public:
	//@隐藏{
	CSysDateTime();
	//@隐藏}
	tm m_tm;

	//@别名 取年()
	int getYear();
	//@别名 取月()
	int getMonth();
	//@别名 取日()
	int getDay();
	//@别名 取时()
	int getHour();
	//@别名 取分()
	int getMinute();
	//@别名 取秒()
	int getSecond();
	//@别名 取周()
	int getDayOfWeek();

	//operator=
	//operator+
	//operator-
	//operator<
	//operator>
	//operator==
	//operator<=
	//operator>=
	//operator!=
};

//@别名 取当前时间(格式字符串)
const wchar_t* GetTimeString_temp(const wchar_t *format);

//@备注 获取当时间,固定格式 例如: 2020-10-29 12:05:03
//@别名 取当前时间2()
const wchar_t*  GetTime_temp();

//@备注 固定格式 例如: 2020-10-29
//@别名 取日期()
const wchar_t* GetDate_temp();

/*@声明
//@返回 返回秒数
//@别名 取时间间隔()
double difftime(INT64 t1, INT64 t2);

//@备注  返回自1970年1月1日午夜以来经过的秒数，如果出现错误，则返回-1。
//@别名  取系统时间(参数等于返回值_填空即可)
INT64 time(INT64 *timer);

//@备注  转换时间值并更正当地时区
//@别名  转换到本地时间()
int localtime_s(tm* _tm, const INT64 *time);

//@别名 格式化时间()
size_t wcsftime(wchar_t *strDest, size_t maxsize, const wchar_t *format, const tm *timeptr);
*/

//@别名 取某月天数()
int GetDayInMonth(int y, int m);


//@分组}

//--------------------------------------------------
//@分组{  控制台操作
/*@声明
//@参数 str 输出字符串
//@参数 stream 指向文件指针, 例如控制台:stdout, stdin, stderr
//@返回 如果成功返回一个非负值。 出现错误-1
//@备注 将字符串写入流
//@别名 标准输出A()
int fputs(const char *str, FILE *stream);

//@参数 str 输出字符串
//@参数 stream 指向文件指针, 例如控制台:stdout, stdin, stderr
//@返回 如果成功返回一个非负值。 出现错误-1
//@备注 将字符串写入流
//@别名 标准输出()
int fputws(const wchar_t *str,FILE *stream);

//@参数  buffer 内存块指针
//@参数  sizeInCharacters  内存块大小, 字符为单位
//@返回  如果成功返回内存块指针,失败返回NULL
//@备注 从 stdin 流中获取一行
//@别名 标准输入A(内存块指针, 内存块大小)
char *gets_s(char *buffer,size_t sizeInCharacters);

//@参数  buffer 内存块指针
//@参数  sizeInCharacters  内存块大小, 字符为单位
//@返回  如果成功返回内存块指针,失败返回NULL
//@备注 从 stdin 流中获取一行
//@别名 标准输入(内存块指针, 内存块大小)
wchar_t *_getws_s(wchar_t *buffer,size_t sizeInCharacters);

//@别名 打印A(格式字符串,参数)
int printf_s(const char *format,...);

//@别名 打印(格式字符串,参数)
int wprintf_s(const wchar_t *format,...);

//@别名 控制台_置编码()
wchar_t* _wsetlocale(int _Category,const wchar_t* _Locale );
*/

//@别名 控制台_置中文编码()
static wchar_t* Console_setlocale_utf8() {	return _wsetlocale(LC_ALL, L"zh_CN.UTF-8"); } //L"zh_CN.UTF-8")

//@别名 控制台_暂停()
static void Console_pause() { system("pause"); }

//@分组}

//--------------------------------------------------
//@分组{  环境存取

/*@声明

//@别名 取命令行()
wchar_t* WINAPI GetCommandLine();

//@别名 取当前进程句柄()
HANDLE WINAPI GetCurrentProcess();

//@参数 pName 欲设置的环境变量的名称。如具有这个名称的一个环境变量尚不存在，则函数会自动创建它
//@参数 pValue 欲为变量设置的新值。
//@别名 置环境变量(名称, 值)
//@返回 返回值：long TRUE（非零）表示成功，否则返回零
BOOL WINAPI SetEnvironmentVariable(const wchar_t* pName, const wchar_t* pValue);
*/

//@别名 取运行目录()
CXText XC_GetRunDir();

//@别名 取当前目录()
CXText XC_GetCurrentDir();

//@别名 取执行文件名()
CXText XC_GetRunFileName();

//@别名 取置环境变量(名称)
CXText XC_GetEnvironmentVariable(const wchar_t* pName);


//@分组}
	
//@分组{  数据结构
/*@声明
//@别名 结构_大小
struct SIZE
{
	int cx; 
	int cy;
};
//@别名 结构_点
struct POINT
{
	int x;
	int y;
};
//@别名 结构_矩形
struct RECT
{
	//@别名 左边
	int left;
	int top;
	int right;
	int bottom;
};
*/
//@分组}

//@分组{  颜色操作

/*@声明
#define  RGB
#define  COLORREF  DWORD

#define  WPARAM  UINT
#define  LPARAM  long
#define  LRESULT long

*/
#ifndef    ARGB_
#define    ARGB_(a,r,g,b)    ((BYTE)a<<24 | (BYTE)r<<16 | (BYTE)g<<8 | (BYTE)b)
#endif

#ifndef   COLORREF_MAKE
#define   COLORREF_MAKE(a,r,g,b)  ((BYTE)a<<24 | (BYTE)r | (BYTE)g<<8 | (BYTE)b<<16)
#endif

#ifndef  GetRValue
//@别名  取颜色值R()
#define GetRValue(rgb)      (LOBYTE(rgb))
//@别名  取颜色值G()
#define GetGValue(rgb)      (LOBYTE(((WORD)(rgb)) >> 8))
//@别名  取颜色值B()
#define GetBValue(rgb)      (LOBYTE((rgb)>>16))
#endif

#ifndef GetAValue
#define GetAValue(rgba)   (LOBYTE((rgba)>>24))
#endif

//@分组}

//@分组{  特殊功能

//@备注  自动分割参数: 参数1, 参数2, 参数3
//@别名  调试输出()
void xc_log(...);

//@备注  不分割参数
//@别名  调试输出2()
void xc_log2(...);

//@别名  调试输出A()
void xc_logA(...);


//@参数 lpText 内容,消息框的内容。
//@参数 lpCaption 标题,消息框的标题
//@别名 信息框(内容, 标题)
void  XC_MsgBox(const wchar_t* pText, const wchar_t* pCaption = NULL);

/*@声明
//@参数 hWnd 窗口句柄,此参数代表消息框拥有的窗口。如果为NULL，则消息框没有拥有窗口。
//@参数 lpText 内容,消息框的内容。
//@参数 lpCaption 标题,消息框的标题
//@参数 uType 标志值,详见MSDN
//@别名 信息框_Ex(父窗口句柄, 内容, 标题, 类型)
//@返回 返回值为:IDOK(1)等详见MSDN
int WINAPI MessageBox(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);
*/

//@分组}

#include "xc_log.h"
#include "xc_logA.h"

//@隐藏{
//----------mkStr-------------------------
template<class T>
CXText mkStr(T t)
{
	wstring strText;
	mkValue(strText, t);
	return strText;
}

template<class T1, class T2>
CXText  mkStr(T1 t1, T2 t2)
{
	wstring strText;
	mkValue(strText, t1);
	mkValue(strText, t2);
	return strText;
}

template<class T1, class T2, class T3>
CXText  mkStr(T1 t1, T2 t2, T3 t3)
{
	wstring strText;
	mkValue(strText, t1);
	mkValue(strText, t2);
	mkValue(strText, t3);
	return strText;
}

template<class T1, class T2, class T3, class T4>
CXText  mkStr(T1 t1, T2 t2, T3 t3, T4 t4)
{
	wstring strText;
	mkValue(strText, t1);
	mkValue(strText, t2);
	mkValue(strText, t3);
	mkValue(strText, t4);
	return strText;
}

template<class T1, class T2, class T3, class T4, class T5>
CXText  mkStr(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
{
	wstring strText;
	mkValue(strText, t1);
	mkValue(strText, t2);
	mkValue(strText, t3);
	mkValue(strText, t4);
	mkValue(strText, t5);
	return strText;
}

template<class T1, class T2, class T3, class T4, class T5, class T6>
CXText  mkStr(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
{
	wstring strText;
	mkValue(strText, t1);
	mkValue(strText, t2);
	mkValue(strText, t3);
	mkValue(strText, t4);
	mkValue(strText, t5);
	mkValue(strText, t6);
	return strText;
}

template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
CXText  mkStr(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
{
	wstring strText;
	mkValue(strText, t1);
	mkValue(strText, t2);
	mkValue(strText, t3);
	mkValue(strText, t4);
	mkValue(strText, t5);
	mkValue(strText, t6);
	mkValue(strText, t7);
	return strText;
}

template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
CXText  mkStr(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
{
	wstring strText;
	mkValue(strText, t1);
	mkValue(strText, t2);
	mkValue(strText, t3);
	mkValue(strText, t4);
	mkValue(strText, t5);
	mkValue(strText, t6);
	mkValue(strText, t7);
	mkValue(strText, t8);
	return strText;
}

template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
CXText  mkStr(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
{
	wstring strText;
	mkValue(strText, t1);
	mkValue(strText, t2);
	mkValue(strText, t3);
	mkValue(strText, t4);
	mkValue(strText, t5);
	mkValue(strText, t6);
	mkValue(strText, t7);
	mkValue(strText, t8);
	mkValue(strText, t9);
	return strText;
}
//@隐藏}
#endif //XC_BASE_H